package it.bsoft.gameboy.memory;

import it.bsoft.bin.util.UByte;
import it.bsoft.bin.util.UShort;
import it.bsoft.gameboy.memory.exception.IllegalMemoryAccessException;

public class Memory {
	
	//each short maps only a byte!
	private short[] memory;
	
	private int byteSize;
	
	private AddressTranslator addrTranslator;
	
	public Memory(int byteSize) {
		this.byteSize = byteSize;
		clear();
	}
	
	public void clear(){
		this.memory = new short[byteSize];
	}
	
	public UByte readByteAt(int offset){
		checkValidOffset(offset);
		return UByte.fromLong(memory[translateAddress(offset)]);
	}
	
	public UShort readShortAt(int offset){
		checkValidOffset(offset);
		int _offset = translateAddress(offset);
		return UShort.fromUBytes(readByteAt(_offset), readByteAt(_offset+1));
	}
	
	
	public void writeByteAt(long toWrite,int offset){
		writeByteAt(UByte.fromLong(toWrite),offset);
	}
	
	public void writeByteAt(UByte toWrite,int offset){
		checkValidOffset(offset);
		this.memory[translateAddress(offset)] = toWrite.shortValue();
	}
	
	public void setMemoryByte(int offset,long... bytes){
		for (int i = 0;i<bytes.length;i++){
			this.writeByteAt(bytes[i], offset+i);
		}
	}
	
	public void setMemoryShort(int offset,long... bytes){
		for (int i = 0;i<bytes.length;i++){
			this.writeShortAt(bytes[i], offset+i);
		}
	}
	
	
	public void writeShortAt(long toWrite,int offset){
		writeShortAt(UShort.fromLong(toWrite),offset);
	}
	
	public void writeShortAt(UShort toWrite,int offset){
		UByte[] uBytes = toWrite.getUBytes();
		writeByteAt(uBytes[0],offset);
		writeByteAt(uBytes[1],offset+1);
	}
	
	private void checkValidOffset(int offset){
		if (offset <0 || offset >= this.memory.length) throw new IllegalMemoryAccessException(offset);
	}
	
	private int translateAddress(int offset){
		if (this.addrTranslator != null) return this.addrTranslator.translate(offset);
		return offset;
	}
	
	public void setAddressTranslator(AddressTranslator t){
		this.addrTranslator = t;
	}
	
}
